<?php

declare(strict_types=1);

namespace app\model\oa;

use think\Model;

/**
 * 发消息模型
 * @package app\model\oa
 */
class Message extends Model
{
    /**
     * 表名（不含前缀）
     * @var string
     */
    protected $name = 'message';

    /**
     * 主键
     * @var string
     */
    protected $pk = 'id';

    /**
     * 自动时间戳
     * @var bool
     */
    protected $autoWriteTimestamp = false;

    /**
     * 创建时间字段
     * @var string
     */
    protected $createTime = 'create_time';

    /**
     * 更新时间字段
     * @var string
     */
    protected $updateTime = 'update_time';

    /**
     * 软删除字段
     * @var string
     */
    protected $deleteTime = 'delete_time';

    /**
     * 接收人类型常量
     */
    const TYPE_USER = 1;     // 人员
    const TYPE_DEPARTMENT = 2; // 部门
    const TYPE_POSITION = 3; // 岗位
    const TYPE_ALL = 4;      // 全部

    /**
     * 消息类型常量
     */
    const IS_DRAFT_NO = 1;   // 正常消息
    const IS_DRAFT_YES = 2;  // 草稿消息

    /**
     * 字段类型映射
     * @var array
     */
    protected $schema = [
        'id' => 'int',
        'title' => 'string',
        'template' => 'string',
        'content' => 'string',
        'file_ids' => 'string',
        'from_uid' => 'int',
        'types' => 'int',
        'uids' => 'string',
        'dids' => 'string',
        'pids' => 'string',
        'copy_uids' => 'string',
        'msg_id' => 'int',
        'is_draft' => 'int',
        'send_time' => 'int',
        'create_time' => 'int',
        'update_time' => 'int',
        'delete_time' => 'int',
        'clear_time' => 'int',
        'action_id' => 'int',
    ];

    /**
     * 关联发送人
     * @return \think\model\relation\HasOne
     */
    public function sender()
    {
        return $this->hasOne('app\model\oa\Admin', 'id', 'from_uid')
            ->field('id,username,nickname,avatar');
    }

    /**
     * 关联模板
     * @return \think\model\relation\HasOne
     */
    public function templateInfo()
    {
        return $this->hasOne('app\model\oa\Template', 'name', 'template')
            ->field('id,title,name,types,remark');
    }

    /**
     * 关联消息记录
     * @return \think\model\relation\HasMany
     */
    public function msgRecords()
    {
        return $this->hasMany('app\model\oa\Msg', 'message_id', 'id');
    }

    /**
     * 获取已发送消息列表
     * @return \think\Paginator
     */
    public static function getSentList()
    {
        return self::where('is_draft', self::IS_DRAFT_NO)
            ->where('send_time', '>', 0)
            ->order('send_time', 'desc')
            ->paginate();
    }

    /**
     * 获取草稿列表
     * @return \think\Paginator
     */
    public static function getDraftList()
    {
        return self::where('is_draft', self::IS_DRAFT_YES)
            ->order('create_time', 'desc')
            ->paginate();
    }

    /**
     * 获取系统消息
     * @return \think\Paginator
     */
    public static function getSystemMessages()
    {
        return self::where('from_uid', 0)
            ->where('is_draft', self::IS_DRAFT_NO)
            ->order('send_time', 'desc')
            ->paginate();
    }

    /**
     * 根据接收人类型获取消息
     * @param int $type
     * @return \think\Paginator
     */
    public static function getByReceiverType(int $type)
    {
        return self::where('types', $type)
            ->where('is_draft', self::IS_DRAFT_NO)
            ->order('send_time', 'desc')
            ->paginate();
    }

    /**
     * 获取消息接收人ID数组
     * @param string $field
     * @return array
     */
    public function getReceiverIds(string $field): array
    {
        $ids = $this->$field ?? '';
        if (empty($ids)) {
            return [];
        }
        return array_filter(array_map('intval', explode(',', $ids)));
    }

    /**
     * 获取所有接收人ID
     * @return array
     */
    public function getAllReceiverIds(): array
    {
        $userIds = $this->getReceiverIds('uids');
        $deptIds = $this->getReceiverIds('dids');
        $posIds = $this->getReceiverIds('pids');

        return [
            'users' => $userIds,
            'departments' => $deptIds,
            'positions' => $posIds,
        ];
    }

    /**
     * 获取抄送人ID数组
     * @return array
     */
    public function getCopyUserIds(): array
    {
        return $this->getReceiverIds('copy_uids');
    }

    /**
     * 获取附件ID数组
     * @return array
     */
    public function getFileIds(): array
    {
        return $this->getReceiverIds('file_ids');
    }

    /**
     * 是否已发送
     * @return bool
     */
    public function isSent(): bool
    {
        return $this->is_draft === self::IS_DRAFT_NO && $this->send_time > 0;
    }

    /**
     * 是否草稿
     * @return bool
     */
    public function isDraft(): bool
    {
        return $this->is_draft === self::IS_DRAFT_YES;
    }

    /**
     * 是否系统消息
     * @return bool
     */
    public function isSystemMessage(): bool
    {
        return $this->from_uid === 0;
    }

    /**
     * 接收人类型描述获取器
     * @param int $value
     * @return string
     */
    public function getReceiverTypeTextAttr(int $value): string
    {
        $typeMap = [
            self::TYPE_USER => '人员',
            self::TYPE_DEPARTMENT => '部门',
            self::TYPE_POSITION => '岗位',
            self::TYPE_ALL => '全部',
        ];
        return $typeMap[$value] ?? '未知';
    }

    /**
     * 草稿状态描述获取器
     * @param int $value
     * @return string
     */
    public function getDraftTextAttr(int $value): string
    {
        return $value === self::IS_DRAFT_YES ? '草稿' : '已发送';
    }

    /**
     * 发送时间格式化获取器
     * @param int $value
     * @return string
     */
    public function getSendTimeTextAttr(int $value): string
    {
        return $value > 0 ? date('Y-m-d H:i:s', $value) : '未发送';
    }

    /**
     * 状态搜索器
     * @param \think\db\Query $query
     * @param mixed $value
     */
    public function searchDraftAttr($query, $value)
    {
        if ($value !== '') {
            $query->where('is_draft', $value);
        }
    }

    /**
     * 接收人类型搜索器
     * @param \think\db\Query $query
     * @param mixed $value
     */
    public function searchTypeAttr($query, $value)
    {
        if ($value !== '') {
            $query->where('types', $value);
        }
    }

    /**
     * 发送人搜索器
     * @param \think\db\Query $query
     * @param mixed $value
     */
    public function searchFromUidAttr($query, $value)
    {
        if ($value !== '') {
            $query->where('from_uid', $value);
        }
    }

    /**
     * 标题搜索器
     * @param \think\db\Query $query
     * @param mixed $value
     */
    public function searchTitleAttr($query, $value)
    {
        if ($value !== '') {
            $query->whereLike('title', '%' . $value . '%');
        }
    }

    /**
     * 内容搜索器
     * @param \think\db\Query $query
     * @param mixed $value
     */
    public function searchContentAttr($query, $value)
    {
        if ($value !== '') {
            $query->whereLike('content', '%' . $value . '%');
        }
    }

    /**
     * 发送时间范围搜索器
     * @param \think\db\Query $query
     * @param array $value
     */
    public function searchSendTimeAttr($query, array $value)
    {
        if (!empty($value[0])) {
            $query->where('send_time', '>=', strtotime($value[0]));
        }
        if (!empty($value[1])) {
            $query->where('send_time', '<=', strtotime($value[1]));
        }
    }
}